home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Pascal / Snippets / Caitlin 1.0 / Caitlin.p next >
Text File  |  1994-03-15  |  6KB  |  169 lines

  1. {Demo program posted on c.s.m.p by John B. Matthews in 1991.}
  2. {Minor modifications, resource and project file added by Ingemar Ragnemalm 1994.}
  3. {(Don't ask me what "Caitlin" is.)}
  4.  
  5. {Some comments on this demo:}
  6. {• No real event processing, which means it's not a "real" program, just an animation until}
  7. {the first mouse click. It does use GetNextEvent, though, so it does allow background tasks to}
  8. {run. (This is no criticism: the demo has no ambition of being a "real" application.)}
  9. {• The animation is not over a detailed background, only over a plain one. We don't really need}
  10. {any offscreen at all to do this. We could simply DrawPicture to the window. The offscreen is}
  11. {only used to hold the picture, which can be a speed advantage, but the PICT works fine too.}
  12. {In other words, this is not what I would call an offscreen demo (like those using a full copy of}
  13. {the screen image plus a second offscreen for a background).}
  14. {• Color QD and GWorlds required – a rather unnecessary limitation for this demo. It's easy to}
  15. {hack around that.}
  16. {• It demonstrates the use of mask regions to make things move "behind" other things. This is,}
  17. {IMHO, the best feature of the code.}
  18.  
  19. {From: jmatthews@desire.wright.edu}
  20. {Newsgroups: comp.sys.mac.programmer}
  21. {Subject: Re: Smooth Flicker Free Animation?}
  22. {Message-ID: <1991Jul29.233551.4286@desire.wright.edu>}
  23. {Date: 30 Jul 91 04:35:51 GMT}
  24. {References: <1991Jul28.201432.23@iscsvax.uni.edu>}
  25. {Organization: University Computing Services, Wright State University}
  26. {Lines: 136}
  27.  
  28. {In article <1991Jul28.201432.23@iscsvax.uni.edu>, hewlitt8882@iscsvax.uni.edu writes:}
  29. {> }
  30. {>         I'm sure this is a FAQ, but I haven't seen any postings of the}
  31. {> answer.  My question is, how does one have very smooth animation without}
  32. {> flicker on the mac.  I have look everywhere for some sample code, but to}
  33. {> no avail.  I'm trying to write a game on my Mac IIsi using Think C 4.0.5.}
  34. {> If someone has some sample code for this procedure or some helpful hints,}
  35. {> I'appreciate the information.  Either post it here, or email it to me.}
  36. {> }
  37. {> Thanks in advanced.}
  38. {> Robert Hewlitt Jr.}
  39.  
  40. {Here's my toy THINK Pascal 3.0 code for playing with offscreen animation. The}
  41. {PICT (id=1000) has a two pixel border so it won't leave a "trail". The}
  42. {CheckDirection proc calls THINK's NOTE proc just to make some noise when the}
  43. {PICT "bounces" off a "wall". The maskRgn is purely decorative-just something}
  44. {for the PICt to slide behind.}
  45.  
  46. {Minor changes for making it run under Think Pascal 4 /Ingemar}
  47.  
  48. program OffscreenTest;
  49.     uses
  50.         QDOffscreen;
  51.     var
  52.         wRect, pRect, dRect: Rect;
  53.         dh, dv: Integer;
  54.         picHdl: PicHandle;
  55.         picWorldPtr: GWorldPtr;
  56.         savePort: CGrafPtr;
  57.         saveGDH: GDHandle;
  58.         wPtr: WindowPtr;
  59.         maskRgn, edgeRgn: RgnHandle;
  60.         theEvent: EventRecord;
  61.         err: QDErr;
  62. {Added by Ingemar:}
  63.         km: KeyMap;
  64.         hasEvent: Boolean;
  65.  
  66.     procedure CalcRegions;
  67.         var
  68.             midH, midV: Integer;
  69.             tempRgn: RgnHandle;
  70.     begin
  71.         maskRgn := NewRgn;
  72.         edgeRgn := NewRgn;
  73.         tempRgn := NewRgn;
  74.         RectRgn(maskRgn, wRect);
  75.         InsetRgn(maskRgn, 35, 35);
  76.         with wRect do
  77.             begin
  78.                 midH := (right - left) div 2;
  79.                 SetRectRgn(tempRgn, midH - 4, top, midH + 4, bottom);
  80.                 DiffRgn(maskRgn, tempRgn, maskRgn);
  81.                 midV := (bottom - top) div 2;
  82.                 SetRectRgn(tempRgn, left, midV - 4, right, midV + 4);
  83.                 DiffRgn(maskRgn, tempRgn, maskRgn);
  84.             end;
  85.         RectRgn(tempRgn, wRect);
  86.         DiffRgn(tempRgn, maskRgn, edgeRgn);
  87.         FillRgn(edgeRgn, dkGray);
  88.         DisposeRgn(tempRgn)
  89.     end;
  90.  
  91.     procedure CheckDirection;
  92.     begin
  93.         with dRect do
  94.             begin
  95.                 if left < wRect.left then
  96.                     begin
  97.                         dh := -dh;
  98.                         Note(300, 200, 1);
  99.                     end;
  100.                 if top < wRect.top then
  101.                     begin
  102.                         dv := -dv;
  103.                         Note(500, 200, 1);
  104.                     end;
  105.                 if right > wRect.right then
  106.                     begin
  107.                         dh := -dh;
  108.                         Note(350, 200, 1);
  109.                     end;
  110.                 if bottom > wRect.bottom then
  111.                     begin
  112.                         dv := -dv;
  113.                         Note(250, 200, 1);
  114.                     end
  115.             end
  116.     end;
  117.  
  118. begin
  119.     InitCursor;
  120.     wRect := screenBits.bounds;
  121.     InsetRect(wRect, 105, 105);
  122.     wPtr := NewCWindow(nil, wRect, 'Caitlin', false, noGrowDocProc, pointer(-1), true, 0);
  123.     wRect := wPtr^.portRect;
  124.     SetPort(wPtr);
  125.     ShowWindow(wPtr);
  126.     CalcRegions;
  127.     picHdl := PicHandle(Get1Resource('PICT', 1000));
  128.     pRect := picHdl^^.picFrame;
  129.     OffsetRect(pRect, -pRect.left, -pRect.top);
  130.     err := NewGWorld(picWorldPtr, 0, pRect, nil, nil, []);
  131.     if (err = noErr) and LockPixels(picWorldPtr^.portPixMap) then
  132.         begin
  133.             GetGWorld(savePort, saveGDH);
  134.             SetGWorld(picWorldPtr, nil);
  135.             EraseRect(pRect);
  136.             DrawPicture(picHdl, pRect);
  137.             SetGWorld(savePort, saveGDH);
  138.             dRect := pRect;
  139.             dh := 1;
  140.             dv := 1;
  141.             repeat
  142.                 CopyBits(GrafPtr(picWorldPtr)^.portBits, GrafPtr(wPtr)^.portBits, pRect, dRect, srcCopy, maskRgn);
  143.                 CheckDirection;
  144.                 OffsetRect(dRect, dh, dv);
  145.  
  146. {Events: use GetNextEvent or GetOSEvent depending on whether or not alt is held down.}
  147. {This was added by Ingemar to show the difference between allowing and disallowing background jobs.}
  148.                 GetKeys(km);
  149.                 if km[58] then
  150.                     hasEvent := GetOSEvent(mDownMask + keyDownMask, theEvent)
  151.                 else
  152.                     hasEvent := GetNextEvent(mDownMask + keyDownMask, theEvent);
  153. {We can replace GNE with WaitNextEvent(mDownMask + keyDownMask, theEvent, 1, nil);}
  154.             until hasEvent;
  155. {until GetNextEvent(mDownMask + keyDownMask, theEvent); {old check.}
  156.             UnlockPixels(picWorldPtr^.portPixMap)
  157.         end;
  158.     DisposeRgn(maskRgn);
  159.     DisposeRgn(edgeRgn);
  160.     DisposeGWorld(picWorldPtr);
  161.     DisposeWindow(wPtr)
  162. end.
  163.  
  164. {Of course, ther's no error chcking; it's just for fun.}
  165. {Hope it helps. John}
  166. {o----------------------------------------------------------------------------o}
  167. {| John B. Matthews, jmatthews@desire.wright.edu, am103@cleveland.freenet.edu |}
  168. {| "Now why would Mike Wallace be standing around on MY porch with a TV crew?"|}
  169. {o----------------------------------------------------------------------------o}